home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher+1.2b4 / gopherd / index.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-15  |  9.3 KB  |  424 lines

  1. /********************************************************************
  2.  * lindner
  3.  * 3.4
  4.  * 1993/04/15 21:41:38
  5.  * /home/mudhoney/GopherSrc/CVS/gopher+/gopherd/index.c,v
  6.  * Exp
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: index.c
  14.  * Routines to deal with various types of indexes.
  15.  *********************************************************************
  16.  * Revision History:
  17.  * index.c,v
  18.  * Revision 3.4  1993/04/15  21:41:38  lindner
  19.  * Added $ to list of naughty characters (just in case)
  20.  *
  21.  * Revision 3.3  1993/04/09  15:54:29  lindner
  22.  * Fixes for indexes with gopher+
  23.  *
  24.  * Revision 3.2  1993/03/26  19:47:06  lindner
  25.  * First crack at gopherplussing Indexing
  26.  *
  27.  * Revision 3.1.1.1  1993/02/11  18:02:52  lindner
  28.  * Gopher+1.2beta release
  29.  *
  30.  * Revision 1.3  1993/01/30  23:57:44  lindner
  31.  * Removed html code, moved parsing of the inputline to gopherd.c
  32.  *
  33.  * Revision 1.2  1992/12/14  21:36:05  lindner
  34.  * Fixed problem in ShellIndexQuery, cp wasn't being incremented.
  35.  * Also added special character elimination from GrepIndexQuery
  36.  *
  37.  * Revision 1.1  1992/12/10  23:13:27  lindner
  38.  * gopher 1.1 release
  39.  *
  40.  *
  41.  *********************************************************************/
  42.  
  43. #include "gopherd.h"
  44. #include "command.h"
  45. #include <stdio.h>
  46.  
  47. #define WAISTYPE 1
  48. #define NEXTTYPE 2
  49. #define SHLLTYPE 3
  50. #define GREPTYPE 4
  51.  
  52.  
  53. void 
  54. Do_IndexTrans(sockfd, IndexDirectory, cmd)
  55.   int sockfd;
  56.   char *IndexDirectory;
  57.   CMDobj *cmd;
  58. {
  59.      char *cp = NULL;
  60.      char *dbName = NULL;
  61.      char INDEXHost[256], INDEXPath[256];  /** Hard coded limits, ugh! **/
  62.      int  INDEXPort=0;
  63.      char logline[256];
  64.      int  Index_type=0;
  65.      char *SearchString = CMDgetSearch(cmd);
  66.      char *view = NULL;
  67.      boolean isgplus;
  68.  
  69.      if (DEBUG)
  70.       printf("Index Dir is %s\n", IndexDirectory);
  71.  
  72.      Index_type = Find_index_type(IndexDirectory);
  73.  
  74.      if (CMDgetCommand(cmd) != NULL) {
  75.       if (*CMDgetCommand(cmd) == '+')
  76.            view = CMDgetCommand(cmd) + 1;
  77.       else if (*CMDgetCommand(cmd) == '$')
  78.            view = "Directory+";
  79.  
  80.       if (*view == '\0')
  81.            view = "Directory";
  82.      }
  83.  
  84.      isgplus = CMDisGplus(cmd);
  85.  
  86.      if (DEBUG) 
  87.       printf("Index type is %d\n", Index_type);
  88.  
  89.      if (Index_type < 0) {
  90.       /**** Error condition, unknown index type... ****/
  91.       Abortoutput(sockfd, "Unknown index type");
  92.       return;
  93.      }
  94.       
  95.      if (Index_type == WAISTYPE) {
  96.       /*** The selector string has both the directory and the dbname... ***/
  97.       cp = strrchr(IndexDirectory, '/');
  98.       
  99.       if (cp == NULL)
  100.            dbName = "index";
  101.       else {
  102.            dbName= cp+1;
  103.            *cp='\0';
  104.       }
  105.      }
  106.  
  107.      if (Read_hostdata(IndexDirectory, INDEXHost, &INDEXPort, INDEXPath, dbName) <0) {
  108.       LOGGopher(sockfd, "Malformed hostdata file\n");
  109.       writestring(sockfd, "0Error on server, malformed hostdata\t\t\t1\r\n.\r\n");
  110.       return;
  111.      }
  112.  
  113.      /* Doctor up the indexdirectory path if we're not running chroot()
  114.       * we use fixfile to keep things secure....
  115.       */
  116.  
  117.      
  118.      /** And call the appropriate query function **/
  119.  
  120.      switch (Index_type) {
  121.  
  122.      case NEXTTYPE:
  123.       
  124.       NeXTIndexQuery(sockfd, SearchString, IndexDirectory, NULL, 
  125.              INDEXHost, INDEXPort, INDEXPath, isgplus, view);
  126.       break;
  127.  
  128.      case WAISTYPE:
  129.       WaisIndexQuery(sockfd, IndexDirectory, SearchString, dbName, 
  130.              INDEXHost, INDEXPort, INDEXPath, isgplus, view);
  131.       break;
  132.  
  133.      case GREPTYPE:
  134.       GrepIndexQuery(sockfd, IndexDirectory, SearchString, 
  135.              INDEXHost, INDEXPort, INDEXPath);
  136.       break;
  137.       
  138.      case SHLLTYPE:
  139.       ShellIndexQuery(sockfd, IndexDirectory, SearchString);
  140.       break;
  141.      }
  142.      
  143.      /** Log it here so we get the query in the logfile **/
  144.  
  145.      if (dbName)
  146.       sprintf(logline, "search %s/%s for %s", IndexDirectory,
  147.           dbName, SearchString);
  148.      else
  149.       sprintf(logline, "search %s for %s", IndexDirectory, SearchString);
  150.  
  151.      LOGGopher(sockfd, logline);
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.  * Try to figure out what each type of object is
  158.  *
  159.  * index types are 
  160.  *   Error       == -1
  161.  *   WAIS        == 1
  162.  *   NeXT        == 2
  163.  *   ShellScript == 3
  164.  *   Grep        == 4
  165.  */
  166.  
  167. int
  168. Find_index_type(gopherpath)
  169.   char *gopherpath;
  170. {
  171.      char Teststr[512];
  172.      FILE *Testfile;
  173.  
  174.      strcpy(Teststr, gopherpath);
  175.      strcat(Teststr, "/.index/index.ixif");
  176.  
  177.      Testfile = rfopen(Teststr, "r");
  178.      if (Testfile != NULL) {
  179.       /*** Next Index ***/
  180.       fclose(Testfile);
  181.       return(NEXTTYPE);
  182.      }
  183.  
  184.  
  185.      strcpy(Teststr, gopherpath);
  186.      strcat(Teststr, ".inv");
  187.  
  188.      Testfile = rfopen(Teststr, "r");
  189.      if (Testfile != NULL) {
  190.       /*** WAIS Index ***/
  191.       fclose(Testfile);
  192.       return(WAISTYPE);
  193.      }
  194.  
  195.  
  196.      strcpy(Teststr, gopherpath);
  197.  
  198.      if (isadir(Teststr) == 1) {
  199.       return(GREPTYPE);
  200.      }
  201.      
  202.      Testfile = rfopen(Teststr, "r");
  203.      if (Testfile != NULL) {
  204.       /** Shell script? **/
  205.       if (getc(Testfile) == '#')
  206.            if (getc(Testfile) == '!') {
  207.             fclose(Testfile);
  208.             return(SHLLTYPE);
  209.            }
  210.      }
  211.  
  212.      return(-1);
  213. }
  214.      
  215.  
  216. /*
  217.  * Read in the data from a hostdata file...
  218.  * 
  219.  * Try "<dbname>.hostdata" first, fall back to "hostdata" otherwise
  220.  */
  221.  
  222. int
  223. Read_hostdata(IndexDirectory, INDEXHost, INDEXPort, INDEXPath, dbName)
  224.   char *IndexDirectory;
  225.   char *INDEXHost, *INDEXPath;
  226.   int  *INDEXPort;
  227.   char *dbName;
  228. {
  229.      FILE *Hostfile;
  230.      char hostdataName[256];
  231.  
  232.      /** Read in the proper hostdata file.... **/
  233.  
  234.      rchdir(IndexDirectory);  /** Change into the index directory **/
  235.  
  236.      sprintf(hostdataName, "%s.hostdata", dbName);  /* try idx.hostdata */
  237.      if ((Hostfile = ufopen(hostdataName, "r")) == NULL)
  238.       Hostfile = ufopen("hostdata", "r");
  239.  
  240.      if (Hostfile == NULL) {
  241.       /*** Use the current host/port as the default ***/
  242.       fclose(Hostfile);
  243.       strcpy(INDEXHost, Zehostname);
  244.       *INDEXPort = GopherPort;
  245.       strcpy(INDEXPath, Data_Dir);
  246.      } 
  247.      else {
  248.       char tempbuf[255];
  249.  
  250.       if (fgets(INDEXHost, 64, Hostfile) == NULL)
  251.            return(-1);
  252.       
  253.       ZapCRLF(INDEXHost);
  254.       
  255.       if (fgets(tempbuf, 255, Hostfile) == NULL)
  256.            return(-1);
  257.       
  258.       if ((*INDEXPort=atoi(tempbuf))==0)
  259.            return(-1);
  260.       
  261.       if (fgets(INDEXPath, 256, Hostfile) == NULL)
  262.            return(-1);
  263.       
  264.       ZapCRLF(INDEXPath);
  265.       fclose(Hostfile);
  266.      }
  267.      
  268.      return(0);
  269. }
  270.  
  271.  
  272. /*
  273.  * This is a searching function that runs grep across files
  274.  * in a single directory...
  275.  */
  276.  
  277. void
  278. GrepIndexQuery(sockfd, Indexdir, Searchstr, INDEXHost, INDEXPort, INDEXPath)
  279.   int sockfd;
  280.   char *Indexdir;
  281.   char *Searchstr;
  282.   char *INDEXHost;
  283.   int INDEXPort;
  284.   char *INDEXPath;
  285. {
  286.      FILE *moocow;
  287.      char command[512];
  288.      char inputline[512];
  289.      char *cp;
  290.      GopherObj *gs;
  291.      GopherDirObj *gd;
  292.  
  293.      gs = GSnew();
  294.      gd = GDnew(32);
  295.  
  296.      cp = Searchstr;
  297.      while (*cp != '\0') {
  298.       if (*cp == ';' ||*cp == '"' || *cp == '`' || *cp == '$')
  299.            *cp = '.';
  300.       cp++;
  301.      }
  302.  
  303.      sprintf(command, "egrep \"%s\" \"%s\"/*", Searchstr, Indexdir);
  304.      if (DEBUG) 
  305.       printf("Grep command is %s\n", command);
  306.  
  307.      moocow = popen(command, "r");
  308.      
  309.      if (moocow == NULL) {
  310.       writestring(sockfd, ".\r\n");
  311.       LOGGopher(sockfd, "Couldn't open grep command");
  312.       return;
  313.      }
  314.  
  315.      while (fgets(inputline, 512, moocow)) {
  316.       ZapCRLF(inputline);
  317.       GSsetType(gs, '0');
  318.  
  319.       cp = strstr(inputline, INDEXPath) + strlen(INDEXPath);
  320.       GSsetTitle(gs, cp);
  321.  
  322.       cp = strchr(inputline, ':');
  323.       *cp='\0';
  324.       cp =strstr(inputline, INDEXPath) + strlen(INDEXPath);
  325.       GSsetPath(gs, cp);
  326.       GSsetHost(gs, INDEXHost);
  327.       GSsetPort(gs, INDEXPort);
  328.  
  329.       GDaddGS(gd, gs);
  330.      }
  331.      if (UsingHTML)
  332.       GDtoNetHTML(gd, sockfd);
  333.      else {
  334.       GDtoNet(gd, sockfd);
  335.       writestring(sockfd, ".\r\n");
  336.      }
  337.  
  338.      pclose(moocow);
  339. }
  340.  
  341.  
  342.  
  343. /*
  344.  * This starts up a shell script that's defined to be an index gateway
  345.  * 
  346.  * The shell script should write out standard gopher directory protocol.
  347.  */
  348.  
  349. void
  350. ShellIndexQuery(sockfd, Script, Searchstring)
  351.   int sockfd;
  352.   char *Script;
  353.   char *Searchstring;
  354. {
  355.      GopherDirObj *gd;
  356.      char Command[512];
  357.      FILE  *Searchprocess;
  358.      char *cp;
  359.  
  360.      gd = GDnew(32);
  361.  
  362.      /*** Clean up the arguments, remove  ; and " and `**/
  363.      cp = Searchstring;
  364.      while (*cp != '\0') {
  365.       if (*cp == ';' ||*cp == '"' || *cp == '`' || *cp == '$')
  366.            *cp = '.';
  367.       cp++;
  368.      }
  369.       
  370.  
  371.      sprintf(Command, "\"%s\" \"%s\"", Script, Searchstring);
  372.  
  373.      Searchprocess = popen(Command, "r");
  374.  
  375.      if (Searchprocess == NULL) {
  376.       writestring(sockfd, ".\r\n");
  377.       return;
  378.      }
  379.  
  380.      GDfromNet(gd, fileno(Searchprocess), NULL);
  381.      if (UsingHTML)
  382.       GDtoNetHTML(gd, sockfd);
  383.      else {
  384.       GDtoNet(gd, sockfd);
  385.       writestring(sockfd, ".\r\n");
  386.      }
  387.  
  388.      pclose(Searchprocess);
  389.      GDdestroy(gd);
  390. }
  391.  
  392.       
  393. #ifndef WAISSEARCH
  394.  
  395. void
  396. WaisIndexQuery(sockfd, index_directory, SearchWords, new_db_name, INDEXHost, INDEXPort, INDEXPath)
  397.   int sockfd;
  398.   char *index_directory;
  399.   char *SearchWords;
  400.   char *new_db_name;
  401.   char *INDEXHost;
  402.   int  INDEXPort;
  403.   char *INDEXPath;
  404. {
  405.      Abortoutput(sockfd, "Sorry, this isn't a WAIS index...");
  406.      return;
  407. }
  408. #endif 
  409.  
  410. #ifndef NEXTSEARCH
  411. void
  412. NeXTIndexQuery(sockfd, SearchWords, ZIndexDirectory, DatabaseNm, INDEXHost, INDEXPort)
  413.   int sockfd;
  414.   char *SearchWords;
  415.   char *ZIndexDirectory;
  416.   char *DatabaseNm;  /*** Not used by the next indexer... ***/
  417.   char *INDEXHost;
  418.   int INDEXPort;
  419. {
  420.      Abortoutput(sockfd, "This isn't a NeXT... is it?");
  421.      return;
  422. }
  423. #endif
  424.